#include "BrushUnion.h"
#include "Character/monster/MonsterMgr.h"
#include "Character/monster/MonsterRefCfg.h"
#include "Duplicate/IDuplicate.h"
#include "Character/CreatureMgr.h"
#include "Character/newAI/behaviac/CreatureCommonAI.h"

BrushUnion::BrushUnion() :m_pDuplicate(nullptr), m_pBrush(nullptr)
{
	m_bBrushFinish = false;
	m_bStart = false;
	m_brushCurIdx = -1;
	m_maxSize = 0;
	m_mapMonsterDie.clear();
	m_mapBossState.clear();
	m_unionAverageLev = 0;
	m_setAllMons.clear();
	m_stWaveMons.clear();
	m_bWaitBrush = false;
}

BrushUnion::~BrushUnion()
{
	
}

bool BrushUnion::Init(IDuplicate *pDuplicate)
{
	if (nullptr == pDuplicate)
	{
		LogErrFmtPrint("BrushUnion::Init...nullptr == pDuplicate");
		return false;
	}
	m_pDuplicate = pDuplicate;
	AllBrushDataCfg *pAllBrush = m_pDuplicate->GetBrushData();
	if (nullptr != pAllBrush)
	{
		m_pBrush = &pAllBrush->stUnion;
		m_maxSize = m_pBrush->vecBrushData.size();

		//初始记录boss数量
		VecUnionBrushDataCfg::iterator iter = m_pBrush->vecBrushData.begin();
		for (; iter != m_pBrush->vecBrushData.end(); ++iter)
		{
			UnionBrushCfgInfo &cfgInfo = (*iter);
			VecUnionBossMonCfg::iterator iterBoss = cfgInfo.vecBossMons.begin();
			for (; iterBoss != cfgInfo.vecBossMons.end(); ++iterBoss)
			{
				UnionBossMonsCfgInfo &bossInfo = (*iterBoss);
				m_mapBossState[bossInfo.monsId] = 0; //初始设置boss未死亡状态
			}

			//记录小怪
			VecUnionMonCfg::iterator iterMons = cfgInfo.vecMons.begin();
			for (; iterMons != cfgInfo.vecMons.end(); ++iterMons)
			{
				UnionMonCfgInfo &monsInfo = (*iterMons);
				m_setAllMons.insert(monsInfo.monsId);
			}
		}
	}
	else
	{
		LogErrFmtPrint("BrushUnion::Init...nullptr == pAllBrush");
		return false;
	}

	return true;
}

void BrushUnion::UnInit()
{
	g_GetTimerAxis()->KillAllTimer(this);
	m_pDuplicate = nullptr;
	m_pBrush = nullptr;
	m_bStart = false;
	m_bBrushFinish = false;
	m_brushCurIdx = -1;
	m_maxSize = 0;
	m_mapMonsterDie.clear();
	m_mapBossState.clear();
	m_unionAverageLev = 0;
	m_setAllMons.clear();
	m_stWaveMons.clear();
	m_bWaitBrush = false;
}

//获取当前层数
int32_t BrushUnion::CurLayer()
{
	return m_brushCurIdx + 1;
}
//获取总层数
int32_t BrushUnion::TotalLayer()
{
	return m_maxSize;
}

void BrushUnion::StartBrush()
{
	m_bStart = true;
	m_brushCurIdx = 0;
	//开始刷怪的时候取一次工会精英平均等级
	if (nullptr != m_pDuplicate)
	{
		m_unionAverageLev = m_pDuplicate->UnionAverageLev();
	}
	else
	{
		LogErrFmtPrint("BrushUnion::StartBrush....nullptr == m_pDuplicate");
	}
	
	ClearMonsDie();
	BrushMonster();
}

void BrushUnion::StopBrush()
{
	m_bStart = false;
	m_bBrushFinish = true;
	g_GetTimerAxis()->KillAllTimer(this);
}

//是否刷怪完成
bool BrushUnion::FinishBrush()
{
	return m_bBrushFinish;
}

void BrushUnion::BrushUpdate()
{
	if (m_bBrushFinish)
		return;
	CheckMonsEnterArea();
	if (m_brushCurIdx >= m_maxSize-1)
		m_bBrushFinish = true;
}

void BrushUnion::OnTimer(uint32_t nTimerID)
{
	switch (nTimerID)
	{
	case ETimer_ID_BrushBoss:
		{
			BrushBossMonster();
		}
		break;
	case ETimer_ID_NextWave:
		{
			BrushMonster();
		}
		break;
	}
}

void BrushUnion::OnMonterDead(uint64_t monsCid, uint32_t monsId, uint32_t count, int32_t formationId, uint64_t killerCid)
{
	if (nullptr == m_pBrush || nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("[logic] BrushUnion::OnMonterDead....nullptr == m_pBrush || nullptr == m_pDuplicate....monsCid:%lu, monsId:%u, count:%u, formationId:%u,killercid:%lu ", monsCid, monsId, count, formationId, killerCid);
		return;
	}
	int8_t byBoss = 0;
	bool validFlag = ValidMons(monsCid, byBoss);
	LogDebugFmtPrint("[logic] BrushUnion::OnMonterDead....monscid:%lu ,monsId:%u, count:%u, formationId:%u,brush:%d,validFlag:%d ", monsCid, monsId, count, formationId, (int32_t)m_bWaitBrush, (int32_t)validFlag);
	//
	if (m_bWaitBrush || !validFlag)
	{
		uint32_t dupId = m_pDuplicate->GetDuplicateID();
		uint32_t sceneId = m_pDuplicate->GetSceneID();
		LogInfoFmtPrint("[logic] BrushUnion::OnMonterDead....wait brush monster or invalid monster.....dupid:%u, sceneid:%u, m_brushCurIdx:%d, validFlag:%d ", dupId, sceneId, m_brushCurIdx, (int32_t)validFlag);
		return;
	}
	if (nullptr != m_pDuplicate)
	{
		m_pDuplicate->ScoreMonsDie(monsId, count, byBoss, killerCid);
	}
	//更新怪物死亡
	UpdateMonsDie(monsCid, monsId, count);
	//
	if (IsAllDie()) //当前这波怪全部死亡,刷新下一波
	{
		uint32_t dupId = m_pDuplicate->GetDuplicateID();
		uint32_t sceneId = m_pDuplicate->GetSceneID();
		if (m_brushCurIdx >= (m_maxSize-1)) //最后一波怪物全部死亡了，所有的怪物全部刷完了
		{
			LogInfoFmtPrint("[logic] BrushUnion::OnMonterDead....all wave monster has brush....dupid:%u, sceneid:%u, m_brushCurIdx:%d ", dupId, sceneId, m_brushCurIdx);
			return;
		}
		
		LogInfoFmtPrint("[logic] BrushUnion::OnMonterDead....cur wave monster all die.....dupid:%u, sceneid:%u, m_brushCurIdx:%d ", dupId,sceneId, m_brushCurIdx);
		//清空怪物死亡数量,每一波需要重新计数
		ClearMonsDie();
		//当前刷新索引设置为下一波刷新索引
		m_brushCurIdx += 1;
		if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
		{
			LogErrFmtPrint("[logic] BrushUnion::OnMonterDeadxxx....m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize....dupid:%u, sceneid:%u, m_brushCurIdx:%d ", dupId, sceneId, m_brushCurIdx);
			return;
		}	
		UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
		//刷新倒计时
		int32_t millsec = brushInfo.nextBrushSec * 1000;
		//需要通知客户端刷新倒计时
		if (brushInfo.nextBrushTip)
		{
			//通知波数
			NotifyMonsWave(brushInfo.nextBrushSec);
		}
		if (millsec > 0)
		{
			g_GetTimerAxis()->KillTimer(ETimer_ID_NextWave, this);
			g_GetTimerAxis()->SetTimer(ETimer_ID_NextWave, millsec + BROAD_NEXT_WAVE_EX_SEC * 1000, this, 1);
			m_bWaitBrush = true;//等待刷怪
		}
		else
		{
			//没有倒计时，直接刷新
			BrushMonster();
		}
	}
	else if (IsAllMonsDie()) //所有的小怪死亡了
	{
		uint32_t dupId = m_pDuplicate->GetDuplicateID();
		uint32_t sceneId = m_pDuplicate->GetSceneID();
		if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
		{
			LogErrFmtPrint("[logic] BrushUnion::OnMonterDead....m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize....dupid:%u, sceneid:%u, m_brushCurIdx:%d,", dupId, sceneId, m_brushCurIdx);
			return;
		}		
		LogInfoFmtPrint("[logic] BrushUnion::OnMonterDead...start brush bosss .....dupid:%u, sceneid:%u, m_brushCurIdx:%d....", dupId, sceneId, m_brushCurIdx);
		UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
		//小怪刷完了之后就开始倒计时刷boss
		if (brushInfo.bossBrushSec > 0)
		{
			int32_t millsec = brushInfo.bossBrushSec * 1000;
			g_GetTimerAxis()->KillTimer(ETimer_ID_BrushBoss, this);
			g_GetTimerAxis()->SetTimer(ETimer_ID_BrushBoss, millsec, this, 1);
			m_bWaitBrush = true;//等待刷怪
		}
		else
		{
			//直接刷新boss
			BrushBossMonster();
		}
	}
}

//获取boss状态
void BrushUnion::GetBossState(MAP_UINT32_INT8 &mapState)
{
	mapState = m_mapBossState;
}

//获取当前波怪物信息
void BrushUnion::GetCurWaveInfo(int32_t &curWave, int32_t &monsDie, int32_t &totalMons, SET_UINT32 &setBoss)
{
	//玩家进入副本2s之后才开始刷怪的，所以如果是第一个玩家进入副本时，还没开始刷怪，这里针对这种情况特殊处理下
	if (m_brushCurIdx < 0)
	{
		if (m_pBrush && m_pBrush->vecBrushData.size() > 0) //这里只是做一个校验
		{
			curWave = 1;
			monsDie = 0;
			GetWaveMonsNum(0, totalMons, setBoss);
		}
	}
	else
	{
		curWave = CurLayer();
		GetCurMonsNum(monsDie, totalMons);
		GetCurBoss(setBoss);
	}
	
}


//是否是有效怪
bool BrushUnion::ValidMons(uint64_t monsCid, int8_t &byBoss)
{
	SET_UINT64::iterator iter = m_stWaveMons.setMons.find(monsCid);
	if (iter != m_stWaveMons.setMons.end())
	{
		byBoss = 0;
		return true;
	}
	SET_UINT64::iterator iterBoss = m_stWaveMons.setBoss.find(monsCid);
	if (iterBoss != m_stWaveMons.setBoss.end())
	{
		byBoss = 1;
		return true;
	}
	return false;
}

//更新怪物死亡数量
void BrushUnion::UpdateMonsDie(uint64_t monsCid, uint32_t monsId, uint32_t num)
{
	SET_UINT64::iterator iterMons = m_stWaveMons.setMons.find(monsCid);
	if (iterMons != m_stWaveMons.setMons.end())
	{
		m_stWaveMons.setMons.erase(iterMons);
	}
	else
	{
		SET_UINT64::iterator iterBoss = m_stWaveMons.setBoss.find(monsCid);
		if (iterBoss != m_stWaveMons.setBoss.end())
		{
			m_stWaveMons.setBoss.erase(iterBoss);
		}
	}


	MAP_UINT32_UINT32::iterator iter = m_mapMonsterDie.find(monsId);
	if (iter != m_mapMonsterDie.end())
	{
		iter->second += num;
	}
	else
	{
		m_mapMonsterDie[monsId] = num;
	}

	//boss处理
	MAP_UINT32_INT8::iterator iterBoss = m_mapBossState.find(monsId);
	if (iterBoss != m_mapBossState.end())
	{
		if (iterBoss->second <= 0)
		{
			iterBoss->second = 1; //设置为死亡状态
			//通知前端boss状态
			NotifyBossState(iterBoss->first,iterBoss->second);
		}
		
	}

	//通知波数信息
	NotifyWaveInfo();
}

void BrushUnion::NotifyBossState(uint32_t bossId, int8_t state)
{
	if (nullptr == m_pDuplicate)
	{
		return;
	}
	//通知副本中的玩家 怪物序列
	Duplicate_MonsStateRsp rsp;
	DupMonsStateProto *proto = rsp.add_mon_state();
	if (nullptr != proto)
	{
		proto->set_mons_id(bossId);
		proto->set_state(state);
	}
	m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_MONSTER_STATE, &rsp);
}

void BrushUnion::NotifyBossAppear(uint32_t bossId)
{
	if (nullptr == m_pDuplicate)
	{
		return;
	}
	//通知副本中的玩家 boss出现
	Duplicate_NotifyBossAppearRsp rsp;
	rsp.set_boss_id(bossId);
	m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_NOTIFY_BOSS_APPEAR, &rsp);
}

void BrushUnion::NotifyMonsWave(int32_t waveCd)
{
	if (nullptr != m_pDuplicate)
	{
		Duplicate_MonsWaveRsp rsp;
		rsp.set_wave(CurLayer());
		rsp.set_sec(waveCd);
		rsp.set_total_wave(TotalLayer());

		int32_t curWave = 0;
		int32_t dieNum = 0;
		int32_t totalNum = 0;
		SET_UINT32 setBoss;
		setBoss.clear();
		GetCurWaveInfo(curWave, dieNum, totalNum, setBoss);
		rsp.set_total_mons(totalNum);
		SET_UINT32::iterator iterBoss = setBoss.begin();
		for (; iterBoss != setBoss.end(); ++iterBoss)
		{
			rsp.add_boss_lst((*iterBoss));
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_MONSTER_WAVE, &rsp);
	}
}



//获取怪物死亡数量
uint32_t BrushUnion::GetMonsDieNum(uint32_t monsId)
{
	MAP_UINT32_UINT32::iterator iter = m_mapMonsterDie.find(monsId);
	return (iter != m_mapMonsterDie.end()) ? iter->second : 0;
}
//获取所有已经死亡怪物数量
int32_t BrushUnion::GetMonsTotalDieNum()
{
	int32_t total = 0;
	MAP_UINT32_UINT32::iterator iter = m_mapMonsterDie.begin();
	for (; iter != m_mapMonsterDie.end(); ++iter)
	{
		total += iter->second;
	}
	return total;
}
//清空怪物死亡数量
void BrushUnion::ClearMonsDie()
{
	m_mapMonsterDie.clear();
	m_stWaveMons.clear();
}
//当前波是否全部死亡
bool BrushUnion::IsAllDie()
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return false;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushUnion::IsAllDie..nullptr == m_pBrush. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return false;
	}
	if (!IsAllMonsDie())
	{
		return false;
	}
	if (!m_stWaveMons.IsAllDie())
	{
		return false;
	}
	//boss
	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
	VecUnionBossMonCfg::iterator iterBoss = brushInfo.vecBossMons.begin();
	for (; iterBoss != brushInfo.vecBossMons.end(); ++iterBoss)
	{
		UnionBossMonsCfgInfo &bossinfo = (*iterBoss);
		int32_t dieNum = GetMonsDieNum(bossinfo.monsId);
		if (bossinfo.nNum > dieNum)
		{
			return false;
		}
	}
	return true;
}

//当前波的小怪是否全部死亡
bool BrushUnion::IsAllMonsDie()
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return false;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushUnion::IsAllMonsDie..nullptr == m_pBrush. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return false;
	}
	if (!m_stWaveMons.IsAllMonsDie())
	{
		return false;
	}
	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
	//检查小怪
	VecUnionMonCfg::iterator iterMon = brushInfo.vecMons.begin();
	for (; iterMon != brushInfo.vecMons.end(); ++iterMon)
	{
		UnionMonCfgInfo &monsinfo = (*iterMon);
		int32_t dieNum = GetMonsDieNum(monsinfo.monsId);
		if (monsinfo.randNum > dieNum)
		{
			return false;
		}
	}

	return true;
}
//获取制定波怪物总数量和boss id列表
void BrushUnion::GetWaveMonsNum(int32_t idx, int32_t &totalNum, SET_UINT32 &setBoss)
{
	if (nullptr == m_pBrush)
	{
		return;
	}
	if (idx < 0 || idx >= (int32_t)m_pBrush->vecBrushData.size())
	{
		return;
	}

	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(idx);
	//检查小怪
	VecUnionMonCfg::iterator iterMon = brushInfo.vecMons.begin();
	for (; iterMon != brushInfo.vecMons.end(); ++iterMon)
	{
		UnionMonCfgInfo &monsinfo = (*iterMon);
		totalNum += monsinfo.randNum;
	}
	//boss
	VecUnionBossMonCfg::iterator iterBoss = brushInfo.vecBossMons.begin();
	for (; iterBoss != brushInfo.vecBossMons.end(); ++iterBoss)
	{
		UnionBossMonsCfgInfo &bossinfo = (*iterBoss);
		setBoss.insert(bossinfo.monsId);
	}
}
//当前波小怪死亡数量和小怪总数量
void BrushUnion::GetCurMonsNum(int32_t &dieNum, int32_t &totalNum)
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushUnion::GetCurMonsNum..nullptr == m_pBrush. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return;
	}
	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
	//检查小怪
	VecUnionMonCfg::iterator iterMon = brushInfo.vecMons.begin();
	for (; iterMon != brushInfo.vecMons.end(); ++iterMon)
	{
		UnionMonCfgInfo &monsinfo = (*iterMon);
		dieNum += GetMonsDieNum(monsinfo.monsId);
		totalNum += monsinfo.randNum;
	}
}
//当前波BOSS死亡数量和BOSS总数量
void BrushUnion::GetCurBoss(SET_UINT32 &setBoss)
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushUnion::GetCurBoss..nullptr == m_pBrush. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return;
	}
	//boss
	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
	VecUnionBossMonCfg::iterator iterBoss = brushInfo.vecBossMons.begin();
	for (; iterBoss != brushInfo.vecBossMons.end(); ++iterBoss)
	{
		UnionBossMonsCfgInfo &bossinfo = (*iterBoss);
		setBoss.insert(bossinfo.monsId);
	}
}

//通知波数信息
void BrushUnion::NotifyWaveInfo()
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return;
	}
	Duplicate_NotifyWaveInfoRsp rsp;
	DupCloudWaveProto *proto = rsp.mutable_wave_info();
	if (nullptr != proto)
	{
		int32_t curWave = 0;
		int32_t dieNum = 0;
		int32_t totalNum = 0;
		SET_UINT32 setBoss;
		setBoss.clear();
		GetCurWaveInfo(curWave, dieNum, totalNum, setBoss);
		proto->set_wave(curWave);
		proto->set_mons_die(dieNum);
		proto->set_total_mons(totalNum);
		SET_UINT32::iterator iterBoss = setBoss.begin();
		for (; iterBoss != setBoss.end(); ++iterBoss)
		{
			proto->add_boss_lst((*iterBoss));
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_NOTIFY_WAVE_INFO, &rsp);
	}
}

//更新区域数量
void BrushUnion::UpdateAreaNum(MAP_UINT32_UINT32 &mapAreaNum, uint32_t areaId, uint32_t num)
{
	MAP_UINT32_UINT32::iterator iter = mapAreaNum.find(areaId);
	if (iter != mapAreaNum.end())
	{
		iter->second += num;
	}
	else
	{
		mapAreaNum[areaId] = num;
	}
}
//获取一个最小区域计数的区域
uint32_t BrushUnion::GetMinNumArea(MAP_UINT32_UINT32 &mapAreaNum,SET_UINT32 &setArea)
{
	uint32_t tmpNum = 0;
	uint32_t dstAreaId = 0;
	uint32_t dstNum = 0;
	SET_UINT32::iterator iterArea = setArea.begin();
	for (; iterArea != setArea.end(); ++iterArea)
	{
		uint32_t areaId = (*iterArea);
		tmpNum = 0;
		MAP_UINT32_UINT32::iterator iterNum = mapAreaNum.find(areaId);
		if (iterNum != mapAreaNum.end())
		{
			tmpNum = iterNum->second;
		}

		if (0 == dstAreaId)
		{
			dstAreaId = areaId;
			dstNum = tmpNum;
		}
		else if (dstNum > tmpNum)
		{
			dstAreaId = areaId;
			dstNum = tmpNum;
		}

		if (dstNum <= 0)
		{
			break;
		}
	}
	return dstAreaId;
}

//刷怪
void BrushUnion::BrushMonster()
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushUnion::BrushMonster..nullptr == m_pBrush. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return;
	}
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("BrushUnion::BrushMonster..nullptr == m_pDuplicate. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return;
	}
	m_bWaitBrush = false;
	uint32_t dupId = m_pDuplicate->GetDuplicateID();
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	MAP_UINT32_UINT32 mapAreaNum;
	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
	VecUnionMonCfg::iterator iterMon = brushInfo.vecMons.begin();
	for (; iterMon != brushInfo.vecMons.end(); ++iterMon)
	{
		UnionMonCfgInfo &monsInfo = (*iterMon);
		mapAreaNum.clear();
		for (int32_t i = 0; i < monsInfo.randNum; ++i)
		{
			uint32_t areaId = GetMinNumArea(mapAreaNum, monsInfo.setArea);
			Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
			MonsterExtendInfo protoEx;
			protoEx.set_level(m_unionAverageLev);
			Point3<float> curDir = Point3<float>(0, 0, 1);
			MonsCreateParam createParam;
			createParam.createType = EMonsCreateType_Dup;
			createParam.createTypeVal = m_pDuplicate->GetDuplicateID();
			Monster *pMonster = g_GetCreatureMgr()->CreateMonster(monsInfo.monsId, sceneId, pos, createParam, curDir, -1, &protoEx);
			if (nullptr != pMonster)
			{
				LogDebugFmtPrint("[logic] BrushUnion::BrushMonster...mons_cid:%lu, monsid:%u,pos:[%f,%f,%f],dupid:%u, sceneid:%u,idx:%d,areaId:%u,m_unionAverageLev:%d ", pMonster->GetCid(), monsInfo.monsId, pos.x, pos.y, pos.z, dupId, sceneId, m_brushCurIdx, areaId, m_unionAverageLev);
				//
				UpdateAreaNum(mapAreaNum, areaId, 1);
				//
				m_stWaveMons.setMons.insert(pMonster->GetCid());
			}
			else
			{
				LogErrFmtPrint("[logic] BrushUnion::BrushMownster...nullptr == pMonster  monsid:%u,pos:[%f,%f,%f], dupid:%u, sceneid:%u,idx:%d, areaId:%u..", monsInfo.monsId, pos.x, pos.y, pos.z, dupId, sceneId, m_brushCurIdx, areaId);
			}
		}
	}
}

//刷boss怪
void BrushUnion::BrushBossMonster()
{
	if (m_brushCurIdx < 0 || m_brushCurIdx >= m_maxSize)
	{
		return;
	}
	if (nullptr == m_pBrush)
	{
		LogErrFmtPrint("BrushUnion::BrushBossMonster..nullptr == m_pBrush. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return;
	}
	if (nullptr == m_pDuplicate)
	{
		LogErrFmtPrint("BrushUnion::BrushBossMonster..nullptr == m_pDuplicate. m_brushCurIdx:%d,m_maxSize:%d", m_brushCurIdx, m_maxSize);
		return;
	}
	m_bWaitBrush = false;
	uint32_t dupId = m_pDuplicate->GetDuplicateID();
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	UnionBrushCfgInfo &brushInfo = m_pBrush->vecBrushData.at(m_brushCurIdx);
	VecUnionBossMonCfg::iterator iterBoss = brushInfo.vecBossMons.begin();
	for (; iterBoss != brushInfo.vecBossMons.end(); ++iterBoss)
	{
		UnionBossMonsCfgInfo &bossinfo = (*iterBoss);
		for (int32_t i = 0; i < bossinfo.nNum; ++i)
		{
			Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(bossinfo.areaId);
			MonsterExtendInfo protoEx;
			protoEx.set_level(m_unionAverageLev);
			Point3<float> curDir = Point3<float>(0, 0, 1);
			MonsCreateParam createParam;
			createParam.createType = EMonsCreateType_Dup;
			createParam.createTypeVal = m_pDuplicate->GetDuplicateID();
			Monster *pMonster = g_GetCreatureMgr()->CreateMonster(bossinfo.monsId, sceneId, pos, createParam,curDir, -1, &protoEx);
			if (nullptr != pMonster)
			{
				LogDebugFmtPrint("[logic] BrushUnion::BrushBossMonster...mons_cid:%lu, monsid:%u,pos:[%f,%f,%f],dupid:%u, sceneid:%u,idx:%d, m_unionAverageLev:%d ", pMonster->GetCid(), bossinfo.monsId, pos.x, pos.y, pos.z, dupId, sceneId, m_brushCurIdx, m_unionAverageLev);
				//
				NotifyBossAppear(bossinfo.monsId);
				//
				m_stWaveMons.setBoss.insert(pMonster->GetCid());
			}
			else
			{
				LogErrFmtPrint("[logic] BrushUnion::BrushBossMonster...nullptr == pMonster....  monsid:%u,pos:[%f,%f,%f],dupid:%u, sceneid:%u,idx:%d ", bossinfo.monsId, pos.x, pos.y, pos.z, dupId, sceneId, m_brushCurIdx);
			}
		}	
	}
	LogDebugFmtPrint("[logic] BrushUnion::BrushBossMonster....m_brushCurIdx:%d ", m_brushCurIdx);
}

void BrushUnion::CheckMonsEnterArea()
{
	if (nullptr == m_pDuplicate || nullptr == m_pBrush || !m_bStart || m_bBrushFinish)
	{
		return;
	}
	MonsEnterAreaCfgData &stMonsEnterArea = m_pBrush->stMonsEnterArea;
	if (stMonsEnterArea.mapMonsEnterAreaBrush.size() <= 0 && stMonsEnterArea.vecMonsEnterAreaFight.size() <= 0)
	{
		return;
	}
	uint32_t sceneId = m_pDuplicate->GetSceneID();
	uint32_t mapId = m_pDuplicate->GetMapID();
	Scene *pScene = g_GetSceneMgr()->GetScene(sceneId);
	if (nullptr == pScene)
	{
		LogErrFmtPrint("[logic] BrushUnion::CheckMonsEnterArea...nullptr == pScene...sceneid:%u ", sceneId);
		return;
	}
	//校验走进区域该改变战斗方式
	VecMonsEnterAreaFightCfg::iterator iterFight = stMonsEnterArea.vecMonsEnterAreaFight.begin();
	for (; iterFight != stMonsEnterArea.vecMonsEnterAreaFight.end(); ++iterFight)
	{
		MonsEnterAreaFightCfgInfo &fightInfo = (*iterFight);
		MAP_UINT32_SET_UINT64 mapGroupMons;
		mapGroupMons.clear();
		m_pDuplicate->GetMonsByGroup(fightInfo.setMonsTid, mapGroupMons);
		MAP_UINT32_SET_UINT64::iterator iter = mapGroupMons.begin();
		for (; iter != mapGroupMons.end(); ++iter)
		{
			SET_UINT64 &setMons = iter->second;
			SET_UINT64::iterator iterMons = setMons.begin();
			for (; iterMons != setMons.end(); ++iterMons)
			{
				uint64_t monsCid = (*iterMons);
				Monster *pMonster = pScene->GetMonster(monsCid);
				if (nullptr == pMonster)
				{
					m_setEnterAreaFight.insert(monsCid);
					continue;
				}
				SET_UINT64::iterator iterAlreday = m_setEnterAreaFight.find(monsCid);
				if (iterAlreday != m_setEnterAreaFight.end())
				{
					continue;
				}

				Point3<float> pos = pMonster->GetPos();
				if (pScene->InArea(fightInfo.areaId, pos))
				{
					m_setEnterAreaFight.insert(monsCid);
					//进去区域了，改变战斗方式
					CreatureCommonAI *pAi = pMonster->GetAiData();
					if (nullptr != pAi)
					{
						pAi->SetAttackType(fightInfo.toFightType);
					}
				}
			}
		}
	}

	//进入区域刷怪
	SET_UINT32 setDelBrush;
	setDelBrush.clear();
	MapMonsEnterAreaBrushCfg::iterator iterBrush = stMonsEnterArea.mapMonsEnterAreaBrush.begin();
	for (; iterBrush != stMonsEnterArea.mapMonsEnterAreaBrush.end(); ++iterBrush)
	{
		MonsEnterAreaBrushCfgInfo &brushInfo = iterBrush->second;
		Monster *pMonster = pScene->GetMonsterByCfgId(brushInfo.monsId);
		if (nullptr == pMonster)
		{
			continue;
		}

		Point3<float> pos = pMonster->GetPos();
		if (!pScene->InArea(brushInfo.areaId, pos))
		{
			continue;
		}
		setDelBrush.insert(brushInfo.monsId);
		//刷新怪物
		SET_INT32::iterator iterTid = brushInfo.setTid.begin();
		for (; iterTid != brushInfo.setTid.end(); ++iterTid)
		{
			uint32_t tid = (*iterTid);
			const std::vector<MonsterRefLocation>* pVecMonsRefLoc = g_GetMapLocationCfg()->GetMapGroupMonster(mapId, tid);
			if (nullptr == pVecMonsRefLoc)
			{
				continue;
			}
			//
			std::vector<MonsterRefLocation>::const_iterator iterLoc = pVecMonsRefLoc->begin();
			for (; iterLoc != pVecMonsRefLoc->end(); ++iterLoc)
			{
				const MonsterRefLocation &refLoc = (*iterLoc);
				Point3<float> dir(0, 0, 1);
				MonsCreateParam createParam;
				createParam.createType = EMonsCreateType_Dup;
				createParam.createTypeVal = m_pDuplicate->GetDuplicateID();
				Monster *pNewMonster = g_GetCreatureMgr()->CreateMonster(refLoc.m_id, sceneId, refLoc.m_bornPos, createParam, dir, refLoc.m_RefLocIndex, nullptr, 0, refLoc.m_group);
				if (nullptr != pNewMonster)
				{
					LogDebugFmtPrint("[logic] BrushUnion::CheckMonsEnterArea...dupid:%u, sceneid:%u, mapid:%u, monsid:%u,,monsCid:%lu, pos:%f,%f,%f ", m_pDuplicate->GetDuplicateID(), sceneId, mapId, refLoc.m_id, pNewMonster->GetCid(), refLoc.m_bornPos.x, refLoc.m_bornPos.y, refLoc.m_bornPos.z);
				}
				else
				{
					LogErrFmtPrint("[logic] BrushUnion::CheckMonsEnterArea....nullptr == pNewMonster...dupid:%u, sceneid:%u, mapid:%u, monsid:%u, pos:%f,%f,%f ", m_pDuplicate->GetDuplicateID(), sceneId, mapId, refLoc.m_id, refLoc.m_bornPos.x, refLoc.m_bornPos.y, refLoc.m_bornPos.z);
				}
			}
		}
	}
	SET_UINT32::iterator iterDel = setDelBrush.begin();
	for (; iterDel != setDelBrush.end(); ++iterDel)
	{
		stMonsEnterArea.mapMonsEnterAreaBrush.erase((*iterDel));
	}
}
